/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package tako.wisers.com.android.apis.activity;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.TextView;

import tako.wisers.com.android.apis.R;
import tako.wisers.com.android.apis.event.Event;
import tako.wisers.com.android.apis.event.EventBus;
import tako.wisers.com.android.apis.event.MapRouteEvent;
import tako.wisers.com.android.apis.handler.MapRouteHandler;
import tako.wisers.com.android.apis.location.GPSManager;
import tako.wisers.com.android.apis.location.RouteDrawer;
import tako.wisers.com.android.apis.util.Configration;
import tako.wisers.com.android.apis.util.Global;
import tako.wisers.com.android.apis.view.DialogManager;

/**
 * Displays a custom map which shows our current location and the location where
 * the photo was taken.
 */
public class ViewMap extends MapActivity {
	private MapView mMapView;

	private Configration conf;

	private GeoPoint mDestPoint;

	private GeoPoint mStartPoint;

	private Handler mhandler = new Handler();

	private DialogManager mDm;

	private Dialog mReadDialog;

	private GPSManager mGM;
	
	private EventBus mBus;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.view_map);
		
		mBus = EventBus.getInstance();
		conf = Configration.getInstance();
		mDm = new DialogManager(this);

		FrameLayout frame = (FrameLayout) findViewById(R.id.route_frame);
		mMapView = new MapView(this, conf.getProperty(Global.CONF_APIKEY));
		frame.addView(mMapView);

		Intent i = getIntent();
		int mapLatitudeE6 = i.getIntExtra(Global.LATITUDE_E6_EXTRA,
				Integer.MIN_VALUE);
		int mapLongitudeE6 = i.getIntExtra(Global.LONGITUDE_E6_EXTRA,
				Integer.MIN_VALUE);
		intRouteButton(R.id.walk_route);
		intRouteButton(R.id.drive_route);

		mGM = GPSManager.getInstance();
		mStartPoint = mGM.getMapView().getMapCenter();
		mDestPoint = new GeoPoint(mapLatitudeE6, mapLongitudeE6);
		int zoomLevel = getZoom();
		mMapView.getController().setZoom(zoomLevel);

		mReadDialog = mDm.build(Global.READ_DIALOG);
		mReadDialog.show();

		new DrawRouteThread(this);

		mMapView.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				System.gc();
			}
		});
		mMapView.setClickable(true);
		mMapView.setEnabled(true);
		int centerLat = (mapLatitudeE6 + mStartPoint.getLatitudeE6()) / 2;
		int centerLong = (mapLongitudeE6 + mStartPoint.getLongitudeE6()) / 2;
		mMapView.getController().animateTo(new GeoPoint(centerLat, centerLong));
		addZoomControls(frame);
		System.gc();
	}

	private int getZoom() {
		int zoomLevel = mGM.getMapView().getZoomLevel();
		if (zoomLevel > 16)
			zoomLevel = 15;
		return zoomLevel;
	}

	class DrawRouteThread extends Thread {
		private Activity mActivity;

		public DrawRouteThread(Activity activity) {
			mActivity = activity;
			start();
		}

		@Override
		public void run() {
			final RouteDrawer drawRoute = new RouteDrawer(mActivity,
					mStartPoint, mDestPoint, mMapView);
			final boolean isSuccess = drawRoute.draw();
			mhandler.post(new Runnable() {
				public void run() {
					if (mReadDialog != null && mReadDialog.isShowing())
						mReadDialog.dismiss();
					if (!isSuccess) {
						Dialog dialog = mDm.build(Global.WAITING_DIALOG);
						dialog.setTitle(R.string.route_warting);
						dialog.show();
					} else {
						TextView text = (TextView) findViewById(R.id.route_distance_text);
						text.setText(drawRoute.getRouteText());
						mMapView.invalidate();
					}
					System.gc();
				}
			});
		}
	}
	
	private void intRouteButton(int id){
		View button = findViewById(id);
		mBus.signinEvent(id, new MapRouteHandler(this), Event.EVENT_CLICK);
		button.setOnClickListener(new OnClickListener(){
			public void onClick(View v) {
				Intent intent = getIntent();
				intent.removeExtra(Global.ROUTE_MODE);
				intent.putExtra(Global.ROUTE_MODE, v.getId());
				mReadDialog = mDm.build(Global.READ_DIALOG);
				mReadDialog.show();
				new DrawRouteThread(ViewMap.this);
			}
		});
	}

	/**
	 * Get the zoom controls and add them to the bottom of the map
	 */
	private void addZoomControls(FrameLayout frame) {
		View zoomControls = mMapView.getZoomControls();

		FrameLayout.LayoutParams p = new FrameLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,
				Gravity.BOTTOM + Gravity.CENTER_HORIZONTAL);
		frame.addView(zoomControls, p);
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK && mMapView != null) {
			MapController controller = mMapView.getController();
			controller.setCenter(mStartPoint);
			controller.setZoom(getZoom());
			mMapView = null;
			System.gc();
			finish();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

}
